- TRABAJANDO CON PELÍCULAS
TRABAJANDO CON PELÍCULAS
En esta ocasión nos encontraremos trabajando con un archivo de datos que contiene información sobre las películas y series de Netflix, la famosa plataforma de streaming. Los datasets que utilizaremos a continuación fueron descargados de Kaggle:
- https://www.kaggle.com/datasets/shivamb/netflix-shows
- https://www.kaggle.com/datasets/dharmikdonga/academy-awards-dataset-oscars
Como ya hemos visto en los ejemplos anteriores, para poder comenzar a trabajar con los archivos, primero debemos importar aquellas librerías que tienen las funcionalidades que nos interesan. Por ello, importaremos Pandas, y también probaremos por primera vez las herramientas de visualización de gráficos que nos provee Plotly, comparándolas con las ya trabajadas de Matplotlib.
Preparando el Dataset de Netflix¶
import pandas as pd
import plotly.express as px
En un principio nos concentraremos solamente en el archivo de películas y series de Netflix. Leemos con pandas el archivo .csv y lo guardamos en la variable netflix_completo.
A su vez, queremos saber con que datos contamos, y sobre la tabla utilizamos la funcion .head(10) para que se nos muestren las primeras 10 filas que contiene.
netflix_completo = pd.read_csv("netflix_titles.csv")
netflix_completo.head(10)
Como podemos ver, la tabla contiene las siguientes columnas:
1) show_id: contiene el identificador único de cada fila.
2) type: corresponde con el tipo de contenido. Si es una película (Movie) o serie (TV Show).
3) title: título de la serie/película.
4) director: director de la serie/película.
5) cast: actores y actrices que forman parte del elenco.
6) country: país de origen de la serie/película.
7) date_added: fecha en la que se agregó a la lista de contenido de Netflix.
8) release_year: fecha en la que se estrenó la serie/película.
9) rating: clasificación de la serie/película de acuerdo a las edades que se recomienda que puedan verlas.
10) duration: duración de las series/películas. Las películas se encuentran medidas en minutos, mientras que las series, en cantidad de temporadas.
11) listed_in: genéros del contenido (fantasía, horror, comedia, etc).
12) description: breve descripción de la serie/película.
Nos deshacemos de aquellas filas que tienen valores NaN, lo que significa que no hay un valor, para lo cual usamos dropna que elimina las filas que contienen este tipo de valores. También vemos el dataframe resultante.
netflix_completo_sin_na = netflix_completo.dropna()
netflix_completo_sin_na.head(10)
Como se puede ver en el dataframe de arriba, el índice de la tabla quedó sin las filas borradas, dejando huecos a lo largo del índice del Dataframe. para que vuelva a estar ordenado y sin índices faltantes usamos reset_index, con el parámetro drop=True que evita que el índice anterior se agregue como columna.
netflix_completo=netflix_completo_sin_na.reset_index(drop=True)
netflix_completo_sin_na.head(10)
Ahora sí, una vez limpiados los datos de la tabla, debemos hacernos la pregunta: ¿Qué información podría obtener en base a los datos que me provee?. Nosotros ya nos hicimos esa misma pregunta, y llegamos a los siguientes interrogantes:
- ¿Cuál es la cantidad de películas y/o series estrenadas por año, que contiene la plataforma Netflix?
- ¿Cuáles son los 5 directores que dirigieron las películas más largas en Netflix?
- ¿Cuáles son las series de origen estadounidense, con más temporadas?
De entre esas, elegimos la primera para resolver, las demás quedan para futuros análisis.
Pregunta: ¿Cuál es la cantidad de películas y series estrenadas por año en Netflix?¶
Primero separamos las columnas que vamos a usar para nuestro análisis: type (Si es película o serie de TV), release_year (Año de estreno) y show_id (Necesario para poder agrupar después).
contenido_por_anio = netflix_completo[["show_id","type","release_year"]]
contenido_por_anio.head(10)
Luego agrupamos los shows por año de estreno y tipo (si es Película o show de TV).
Luego usamos la columna show_id con count para contar la cantidad de elementos en cada subgrupo.
contenido_por_anio = contenido_por_anio.groupby(["release_year","type"])["show_id"].count()
contenido_por_anio.head(10)
Usamos la función unstack ya que cuando usamos el groupby esto genera un multiíndice (un índice con subgrupos) y para graficarlo necesitamos separarlo.
Finalmenete usamos fillna(0) para indicar qué valores NaN o null deben ser llenados con 0.
contenido_por_anio = contenido_por_anio.unstack().fillna(0)
contenido_por_anio.head(10)
Graficando con matplotlib¶
En el caso de matplotlib, usamos la funcion plot para obtener un gráfico para el cuál especificamos el tamaño con figsize de 15 pulgadas de ancho y 10 pulgadas de alto.
Le agregamos las etiquetas de los ejes x (Año de Estreno) e y (Cantidad) con los parámetros xlabel e ylabel respectivamente.
También para que se noten los estrenos particulares, agregamos markers con marker="o" que nos da un marker circular.
contenido_por_anio.plot(figsize=(15,10), xlabel="Año de estreno", ylabel="Cantidad de estrenos", marker="o")
Graficando con Plotly¶
En el caso de Plotly, usamos plotly express, una versión simplificada, muy parecida a MatPlotLib que nos permite tener gráficos interactivos.
fig= px.line(contenido_por_anio)
fig.show()
Se ve feo, ¿No?
Para cambiarlo hay que agregar algunos parámetros a line que nos van a ayudar con esto.
Para esto usamos el parámetro labels al cual se le debe pasar un diccionario con los valores anteriores de las etiquetas, y los valores nuevos separados por : (dos puntos)
- (value -> Cantidad de estrenos)
- (release_year -> Año de estreno)
- (type -> "")
Finalmente como en el gráfico de MatPlotLib le colocamos los markes, est
fig= px.line(contenido_por_anio,labels={"value":"Cantidad de estrenos","release_year":"Año de estreno","type":""}, markers=True)
fig.show()
Si hacemos zoom en el gráfico anterior podemos ver que las escalas de los años y las cantidades llegan, por ejemplo, a 112,5 estrenos; para que las escalas se vean correctamente hay que aclarar la unidad de la escala en cada eje, esto lo hacemos con: update_yaxes(dtick=100) y update_yaxes (dtick=100) que para el eje correspondiente aclaran la unidad en 100 y 1 respectivamente.
fig.update_yaxes(dtick=100)
fig.update_xaxes(dtick=1)
fig.show()
Preparando el Dataset de los Oscars¶
Para la siguiente demostración vamos a usar el dataset de los Oscars, que está en formato xlsx, el formato de excel, entonces usamos read_excel
oscars = pd.read_excel("oscars.xlsx")
oscars.head(10)
Como podemos ver, la tabla contiene las siguientes columnas:
1) year_film: Año de estreno de la película.
2) year_ceremony: Año de la ceremonia de premiación en que la película calificó.
3) ceremony: Numero de ceremonia en que la película calificó.
4) Category: Categoría de la nominación (Mejor actriz, mejor película, etc).
5) gender: Genero de quien fue nominado/a.
6) name: Nombre del nominado/a.
7) Race: Etnia del nominado/a.
8) film: Nombre de la película correspondiente a la nominación.
9) winner: Si ganó o no.
Ahora tenemos que ver como con el dataset de Netflix, si hay valores nulos:
oscars.isnull().values.any()
Como hay valores nulos, tenemos que borrar esas filas con dropna y arreglar el índice con reset_index:
oscars = oscars.dropna().reset_index(drop=True)
Revisamos de vuelta para confirmar
oscars.isnull().values.any()
Pregunta: ¿Cuál es la etnia de los ganadores de Oscars año a año?¶
Primero separamos las columnas necesarias: la etnia, el año de la ceremonia y si ganó o no.
dataframe_race_year = oscars[["Race","year_ceremony","winner"]]
dataframe_race_year.head(10)
Luego filtramos para quedarnos solo con los ganadores.
dataframe_winners = dataframe_race_year[dataframe_race_year.winner == True]
dataframe_winners.head(10)
Ahora agrupamos los datos por el año y la etnia con groupby y usamos la columna winner para contar la cantidad de elementos de cada subgrupo.
group_race_year= dataframe_winners.groupby(["year_ceremony","Race"])["winner"].count()
group_race_year.head(10)
Una vez hecho esto usamos unstack para deshacernos del multiíndice generado con el groupby y el fillna para llenar los casos donde una etnia no ganó premios ese año.
group_race_year= group_race_year.unstack().fillna(0)
group_race_year.head(10)
Graficando con MatPlotLib¶
Para graficar esto con MatPlotLib usamos plot y cambiamos las etiquetas de los ejes por etiquetas más explicativas.
group_race_year.plot(figsize=(15,10),grid=True,xlabel="Año de la ceremonia",ylabel="Cantidad de ganadores")
Graficando con Plotly¶
En el caso de Plotly es muy parecido. Cambiamos las etiquetas y como en el caso anterior usamos unidades apropiadas para las escalas.
fig = px.line(group_race_year,labels={"value":"Cantidad de Oscars","year_ceremony":"Año de la ceremonia"},markers=True)
fig.update_yaxes(dtick=1)
fig.update_xaxes(dtick=10)
fig.show()
Pregunta: ¿Cuáles son las 10 películas de Netflix con más Oscars ganados?¶
Este análisis es más complicado que los anteriores, ya que usamos dos datasets distintos y los unimos para sacar conclusiones más complejas que con uno solo.
Primero separamos las columnas del dataset de oscars que necesitamos para el análisis, film (Las películas) y winner (si ganó o no) y elegimos solo a los que ganaron.
oscars_de_peliculas = oscars[["film","winner"]]
oscars_de_peliculas = oscars_de_peliculas[oscars_de_peliculas["winner"] == True]
oscars_de_peliculas.head(10)
Hacemos lo mismo con los shows de netflix, con las columnas type (si es película o TV) y title (los shows) y elegimos solo las películas preguntando por el tipo.
peliculas = netflix_completo[["type","title"]]
peliculas = peliculas[peliculas["type"] == "Movie"]
peliculas.head(10)
Ahora, ya que ya usamos las columnas winner del dataset de oscars y type del de Netflix y ya no aportan nada, los borramos.
oscars_de_peliculas= oscars_de_peliculas[["film"]]
oscars_de_peliculas.head(10)
peliculas = netflix_completo[["title"]]
peliculas.head(10)
El siguiente paso es unir las tablas para quedarnos solo con las películas que ganaron oscars y están en netflix; para luego contar la cantidad de apariciones de cada una.
Para hacer la unión de las tablas usamos join sobre el dataset de Netflix, esto nos permite unir las tablas, los parámetros que le pasamos son el otro dataframe con el index que vamos a usar, on la columna del otro dataset por la que los vamos a unir y how que indica como se va a hacer, en este caso se aclara inner, que solo deja filas que coincidan el mismo título en ambos datasets.
peliculas_con_oscars = peliculas.join(oscars_de_peliculas.set_index("film"), on = "title", how = "inner")
peliculas_con_oscars.head(10)
Ahora lo que queda por hacer es agrupar las películas según su título:
# peliculas_con_oscars.groupby(['title'])
Encontrar el tamaño de cada grupo:
# .size()
Ordenarlos de mayor a menor:
# sort_values(ascending = False)
Y obtener los 10 primeros:
# .head(10)
peliculas_con_oscars = peliculas_con_oscars.groupby(['title']).size().sort_values(ascending = False).head(10)
peliculas_con_oscars.head(10)
Graficando con Plotly¶
fig = px.bar(peliculas_con_oscars,labels={'x': 'Título', 'y':'Cantidad de Oscars'}, title="10 películas en Nextflix con más Oscars ganados.")
fig.update_yaxes(dtick=1)
fig.show()
Graficando con MatPlotLib¶
peliculas_con_oscars.plot(kind="bar",xlabel= "Título",ylabel= "Cantidad de Oscars", legend= False, title = "10 películas en Nextflix con más Oscars ganados.", figsize = (15, 10))